package com.axend.vetwavve.fragment.startmonitoring

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.app.Activity
import android.app.Dialog
import android.content.BroadcastReceiver
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.SurfaceTexture
import android.hardware.Camera
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbManager
import android.media.projection.MediaProjectionManager
import android.os.Build
import android.os.Bundle
import android.os.SystemClock
import android.util.Log
import android.util.Size
import android.view.Surface
import android.view.SurfaceHolder
import android.view.TextureView
import android.view.View
import android.view.WindowManager
import android.view.animation.AnimationUtils
import android.widget.FrameLayout
import android.widget.ImageView
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.widget.AppCompatImageView
import androidx.camera.core.CameraSelector
import androidx.camera.core.Preview
import androidx.camera.core.resolutionselector.ResolutionSelector
import androidx.camera.core.resolutionselector.ResolutionStrategy
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.android.jws.JwsManager
import com.axend.lib_base.base.fragment.BaseVVDInfraredCameraFragment
import com.axend.lib_base.bean.AlarmTag
import com.axend.lib_base.bean.DefaultThresholdType.Companion.getDefaultThresholdType
import com.axend.lib_base.bean.RadarBpmData
import com.axend.lib_base.bean.RadarData
import com.axend.lib_base.bean.RadarUpBean
import com.axend.lib_base.bean.SpeciesType.Companion.getSpeciesType
import com.axend.lib_base.bean.TempType
import com.axend.lib_base.bean.TempType.Companion.getTempType
import com.axend.lib_base.engine.toast.toast
import com.axend.lib_base.ext.addFragment
import com.axend.lib_base.ext.celsiusToFahrenheit
import com.axend.lib_base.ext.clearAllFragments
import com.axend.lib_base.ext.click
import com.axend.lib_base.ext.dp2px
import com.axend.lib_base.ext.expandTouchArea
import com.axend.lib_base.ext.mToCm
import com.axend.lib_base.ext.mToIn
import com.axend.lib_base.ext.replaceFragment
import com.axend.lib_base.ext.roundToFloatOneDecimal
import com.axend.lib_base.ext.roundToNearestInteger
import com.axend.lib_base.ext.roundToNoDecimalPlaces
import com.axend.lib_base.ext.roundToOneDecimalPlace
import com.axend.lib_base.ext.runOnUIThread
import com.axend.lib_base.ext.toByteArray
import com.axend.lib_base.ext.toFloatOrDefault
import com.axend.lib_base.ext.toPlainStringNoRounding
import com.axend.lib_base.ext.toPlainStringNoRoundingSix
import com.axend.lib_base.ext.toStrOrDefault
import com.axend.lib_base.help.TempMeasure
import com.axend.lib_base.help.otgserial.DataSender
import com.axend.lib_base.help.otgserial.RadarCommand
import com.axend.lib_base.help.otgserial.SerialInter
import com.axend.lib_base.help.otgserial.SerialManage
import com.axend.lib_base.utils.AudioPlayer
import com.axend.lib_base.utils.BitmapToVideo
import com.axend.lib_base.utils.ByteUtils.byteArrayToCommaSeparatedString
import com.axend.lib_base.utils.DateUtils
import com.axend.lib_base.utils.DateUtils.getCurrentDateTime
import com.axend.lib_base.utils.FileOutputUtil
import com.axend.lib_base.utils.ScreenAutoAdapter
import com.axend.lib_base.utils.ThreadPoolUtils
import com.axend.lib_base.utils.USBTransferUtil
import com.axend.lib_base.view.RectangleView
import com.axend.lib_base.view.dialog.CustomAlarmDialog
import com.axend.lib_base.view.dialog.CustomCountDownDialog
import com.axend.lib_base.view.dialog.CustomTempCalibrateDialog
import com.axend.lib_base.view.dialog.CustomWarningDialog
import com.axend.lib_room.entity.PetInfoEntity
import com.axend.lib_service.Constant.designSize
import com.axend.vetwavve.BR
import com.axend.vetwavve.activity.MainActivity
import com.axend.vetwavve.databinding.FragmentStartMonitoringBinding
import com.axend.vetwavve.fragment.AddOrEditRecordFragment
import com.axend.vetwavve.fragment.DeskTopFragment
import com.axend.vetwavve.helper.ChartHelper
import com.axend.vetwavve.helper.ChartHelper.initLineChart
import com.axend.vetwavve.helper.ChartHelper.startHeartEcgChart
import com.axend.vetwavve.helper.ChartHelper.stopEcgChartTimer
import com.axend.vetwavve.helper.ChartHelper.updateBreathEcgChart
import com.axend.vetwavve.helper.ChartHelper.updateEntry
import com.axend.vetwavve.helper.EcgChartHelper
import com.axend.vetwavve.helper.Motion2DetectHelper
import com.axend.vetwavve.helper.ScreenRecordService
import com.axend.vetwavve.helper.TrackerHelper
import com.axend.vetwavve.viewmodel.StartMonitoringViewModel
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineDataSet
import com.guide.zx03c.GuideInterface
import com.guide.zx03c.UsbStatusInterface
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.opencv.core.Rect
import java.io.File
import java.io.IOException
import java.lang.Float.intBitsToFloat
import java.nio.ByteBuffer
import java.util.Locale
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit
import kotlin.math.roundToInt
import kotlin.time.Duration.Companion.seconds


/**
 * @description开始监测页面
 * @author admins
 * @time 2024/6/18 11:43
 */
class StartMonitoringFragment :
    BaseVVDInfraredCameraFragment<StartMonitoringViewModel, FragmentStartMonitoringBinding>(),
    UsbStatusInterface, GuideInterface.ImageCallBackInterface,
    SerialInter, USBTransferUtil.OnUSBDateReceive {
    /*video显示隐藏动画效果*/
    private val animationIn by lazy {
        AnimationUtils.loadAnimation(
            requireContext(),
            com.axend.lib_base.R.anim.base_slide_right_in
        )
    }

    private val animationOut by lazy {
        AnimationUtils.loadAnimation(
            requireContext(),
            com.axend.lib_base.R.anim.base_slide_right_out
        )
    }

    /**
     * 警告弹窗
     */
    private val warningDialog by lazy {
        CustomWarningDialog.getInstance(requireContext())
    }

    /**
     * 报警弹窗
     */
    private val alarmDialog by lazy {
        CustomAlarmDialog.getInstance(requireContext())
    }

    /**
     * 断连弹窗
     */
    private val disconnectDialog by lazy {
        CustomCountDownDialog.getInstance(requireContext())
    }


    /**
     * 闪烁动画
     */
    private val hrBlinkAnimation by lazy {
        createBlinkAnimation(mBinding.ivHrAlarmWarning)
    }
    private val rrBlinkAnimation by lazy {
        createBlinkAnimation(mBinding.ivRrAlarmWarning)
    }
    private val tfBlinkAnimation by lazy {
        createBlinkAnimation(mBinding.ivTfAlarmWarning)
    }
    private val videoAnimation by lazy {
        createBlinkAnimation(mBinding.btnShowVideo)
    }

    /**
     * 全局linedatamode
     */
    private var lineDataMode = LineDataSet.Mode.CUBIC_BEZIER

    private var petInfoEntity: PetInfoEntity? = null

    private var pauseOffset = 0L // 用来记录暂停时的偏移量

    private var cameraProvider: ProcessCameraProvider? = null


    private val highCrossWidth = 40
    private val highCrossHeight = 40


    private var tmpChartData: MutableList<Entry> = mutableListOf()
    private var hrChartData: MutableList<Entry> = mutableListOf()
    private var rrChartData: MutableList<Entry> = mutableListOf()

    /**
     * ecgchart
     */
    private var hrEcgChartData: MutableList<Entry> = mutableListOf()
    private var rrEcgChartData: MutableList<Entry> = mutableListOf()

    /**
     * 虚线集合
     */
    private var tmpDashList: MutableList<Entry> = mutableListOf()
    private var hrDashList: MutableList<Entry> = mutableListOf()
    private var rrDashList: MutableList<Entry> = mutableListOf()

    /*雷达数据显示计数*/
    private var radarDataCount: Int = 0
    private var radarDataCountEcg: Int = 79

    /****old camera api*****/
    private var camera: Camera? = null
    private lateinit var surfaceHolder: SurfaceHolder

    private var trackerHelper = TrackerHelper()
    private var MotionDetectHelper: Motion2DetectHelper? = null

    private var oldTempCalibration: Float? = null
    private var bitmapToVideo: BitmapToVideo? = null

    private var mMediaProjectionManager: MediaProjectionManager? = null
    private lateinit var recordLauncher: ActivityResultLauncher<Intent>
    private val tempMeasure: TempMeasure = TempMeasure()

    private val moveTempFileName =
        "moveTemp${File.separator}tempMeasure_${DateUtils.getCurrentTimeStamp()}"
    private val generalTempFileName = "temp${File.separator}temp_${DateUtils.getCurrentTimeStamp()}"


    // 定义一个数据类来存储警告类型和对应的计数器
    data class WarningCounter(val type: String, var count: Int)

    // 创建一个Map来存储所有警告类型的计数器
    private val warningCounters = mutableMapOf<String, WarningCounter>()

    //创建一个Map来存储警告类型时间戳
    private val warningAndAlarmTimeStamps = mutableMapOf<String, Long>()

    //创建一个集合来存储出框值
    private var warningMoveList = CopyOnWriteArrayList<Boolean>()

    //创建数组集合来查看温度是否异常
    private var tempAlarmList = CopyOnWriteArrayList<Boolean>()
    private var tempWarningList = CopyOnWriteArrayList<Boolean>()

    /*移动值*/
    private var bodyMoveFloat = 0f



    companion object {
        fun newInstance(petInfoEntity: PetInfoEntity?): StartMonitoringFragment {
            return StartMonitoringFragment().apply {
                arguments = Bundle().apply {
                    putParcelable(AddOrEditRecordFragment.ARGUMENT_PET_INFO, petInfoEntity)
                }
            }
        }
    }

    override fun getBindingVariable(): Int = BR.viewmodel
    override fun setScale(): Int =
        resources.getDimension(com.axend.lib_base.R.dimen.monitoring_video_width).toInt()

    override fun setUsbStatusInterface(): UsbStatusInterface = this

    override fun setImageCallBackInterface(): GuideInterface.ImageCallBackInterface = this

    override fun init(savedInstanceState: Bundle?) {
        super.init(savedInstanceState)
        // 添加FLAG_KEEP_SCREEN_ON标志使屏幕常亮
        requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
        requireActivity().window.setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
        )

        /*获取参数*/
        petInfoEntity = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            arguments?.getParcelable(
                AddOrEditRecordFragment.ARGUMENT_PET_INFO,
                PetInfoEntity::class.java
            )
        } else {
            arguments?.getParcelable(AddOrEditRecordFragment.ARGUMENT_PET_INFO)
        }
        mViewModel.setPetInfoEntity(petInfoEntity!!)
        // 开始计时
        mBinding.cmTime.apply {
            setOnChronometerTickListener {
                // 计算已过时间
                val timeMillis = SystemClock.elapsedRealtime() - it.base
                // 格式化时间
                val formattedTime = formatTime(timeMillis)
                // 更新Chronometer的显示文本
                it.text = formattedTime
            }
            base = SystemClock.elapsedRealtime()
            start()
        }

        /*初始化红外*/
        /*将红外视图添加到父布局中*/
        mBinding.flVideoContent.addView(mIrSurfaceView)
        irSurfaceViewWidth =
            resources.getDimension(com.axend.lib_base.R.dimen.monitoring_video_width)
        irSurfaceViewHeight =
            resources.getDimension(com.axend.lib_base.R.dimen.monitoring_video_height)
        /*屏幕翻转初始化避免镜像*/
        mBinding.finalCameraSurfaceView.surfaceTextureListener =
            object : TextureView.SurfaceTextureListener {
                override fun onSurfaceTextureAvailable(p0: SurfaceTexture, p1: Int, p2: Int) {
                    val textureView = mBinding.finalCameraSurfaceView
                    // 在这里进行水平翻转
                    val matrix = Matrix()
                    matrix.postScale(
                        -1f,
                        1f,
                        textureView.width.toFloat() / 2,
                        textureView.height.toFloat() / 2
                    )
                    textureView.setTransform(matrix)
                }

                override fun onSurfaceTextureSizeChanged(p0: SurfaceTexture, p1: Int, p2: Int) {

                }

                override fun onSurfaceTextureDestroyed(p0: SurfaceTexture): Boolean {
                    return true
                }

                override fun onSurfaceTextureUpdated(p0: SurfaceTexture) {

                }

            }
        ThreadPoolUtils.init()
        /*初始化雷达连接 usb串口 暂时注释*/
//        USBTransferUtil.getInstance().setOnUSBDateReceive(this)
//        USBTransferUtil.getInstance().connect()
//        UsbUtils.init(requireContext())
//        val filter = IntentFilter()
//        filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
//        filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
//
//        requireActivity().registerReceiver(usbBroadcastReceiver, filter)

        SerialManage.getInstance().init(this, true) //串口初始化
        // GPIO引脚（IO-1）设置为高电平（高电平雷达正常工作；低电平雷达复位）
        val port = 1
        val jwsManager = JwsManager.create(requireContext())
        jwsManager.jwsSetExtrnalGpioValue(port, true)
        /*隐藏状态栏*/
        jwsManager.jwsSetStatusBar(context,false)

        FileOutputUtil.saveRadarData(ThreadPoolUtils.getCachedThreadPool())
        FileOutputUtil.saveRadarBpmData(ThreadPoolUtils.getCachedThreadPool())
        switchChartLine(mBinding.ivChartLineBroken)

        //初始化opencv移动侦测帮助类
        val scale = irSurfaceViewWidth / y16W

        val scaledCenterX = (centerX * 3).toInt()
        val scaledCenterY = (centerY * 3).toInt()
        val scaledWidth: Int = (radius * 2 * 3).toInt()
        val scaledHeight: Int = (radius * 2 * 3).toInt()

        // 计算矩形的左上角和右下角坐标
        val left = scaledCenterX - scaledWidth / 2
        val top = scaledCenterY - scaledHeight / 2
        val right = scaledCenterX + scaledWidth / 2
        val bottom = scaledCenterY + scaledHeight / 2

        MotionDetectHelper = Motion2DetectHelper(Rect(left, top, scaledWidth, scaledHeight))
        bitmapToVideo = BitmapToVideo(y16W * 3, y16H * 3, 1000000, FRAME, 10)
        mMediaProjectionManager =
            requireActivity().getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        rectangleView = RectangleView(requireContext(), Color.GREEN)
        initOnClick()
        initObserver()

    }

    /**
     * 点击事件
     */
    private fun initOnClick() {
        //暂停开始按钮
        mBinding.btnPause.setOnClickListener {
            mViewModel.setIsPause(mViewModel.isPause.value?.not()!!)
        }
        /*显示监控视频*/
        mBinding.llShowVideo.setOnClickListener {
            it.visibility = View.GONE
            mBinding.llShowVideo.startAnimation(animationOut)
            mBinding.flVideo.startAnimation(animationIn)
            mBinding.flVideo.visibility = View.VISIBLE
        }
        /*关闭监控视频*/
        mBinding.llCloseVideo.setOnClickListener {
            mBinding.flVideo.startAnimation(animationOut)
            mBinding.flVideo.visibility = View.INVISIBLE
            mBinding.llShowVideo.visibility = View.VISIBLE
            mBinding.llShowVideo.startAnimation(animationIn)
        }
        /*设置按钮*/
        mBinding.btnSetting.setOnClickListener {
            addFragment(
                activity,
                (activity as MainActivity).getFragmentContainerId(),
                AddOrEditRecordFragment.newInstance(
                    AddOrEditRecordFragment.PARAMS_EDIT,
                    petInfoEntity,
                    this
                ),
                this@StartMonitoringFragment,
                null,
                true
            )
        }
        /*图表线条切换*/
        mBinding.ivChartLineBroken.expandTouchArea(50)
        mBinding.ivChartLineBroken.setOnClickListener {
            switchChartLine(it as AppCompatImageView)
        }
        mBinding.ivChartLineCurved.expandTouchArea(50)
        mBinding.ivChartLineCurved.setOnClickListener {
            switchChartLine(it as AppCompatImageView)
        }
        mBinding.btnBell.setOnClickListener { mViewModel.setIsAlarm(mViewModel.isAlarm.value?.not()!!) }
        /*温度校验按钮*/
        mBinding.btCalibrate.setOnClickListener {
            CustomTempCalibrateDialog(requireContext(),
                getString(com.axend.lib_base.R.string.app_calibrate_title),
                resources.getStringArray(com.axend.lib_base.R.array.app_temp_units)[mViewModel.petInfoEntity.value?.temperatureUnit!!],
                object : CustomTempCalibrateDialog.OnOkListener {
                    override fun onClick(dialog: DialogInterface, value: Float) {
                        if (value == 0f) {
                            toast(getString(com.axend.lib_base.R.string.app_tips_number_null))
                            return
                        }
                        /*计算差值 校准温度-红外温度*/
                        // 校准温度-红外体表温度
                        var maxTempCurrent =
                            if (mViewModel.petInfoEntity.value?.temperatureUnit == 0) {
                                filteredMaxTempStr.toFloatOrDefault(0f).celsiusToFahrenheit()

                            } else {
                                filteredMaxTempStr.toFloatOrDefault(0f)
                            }
                        val tempDiff =
                            (value - maxTempCurrent).roundToFloatOneDecimal()
                        // 校准温度-红外体内温度
//                        val tempDiff =
//                            (value - vivoTempStr.toFloatOrDefault(0f)!!).roundToFloatOneDecimal()
                        petInfoEntity?.let {
                            it.tempCalibration = tempDiff
                            mViewModel.setPetInfoEntity(it)
                        }
                        maxTempCountC = 0
                        maxTempCountF = 0
                        mViewModel.updateParamsToDataBase(petInfoEntity!!) {
                            /*记录一次当前数据存储为txt文本 头部 时间、体表温度、实际温度、体内最高温*/
                            val title = "Time\tbodyMaxTemp\tactualTemp\tvivoMaxTemp";
                            val fileName = getString(com.axend.lib_base.R.string.app_file_temp)
                            FileOutputUtil.writeHeadToFile(fileName, title)
                            val content =
                                "\r\n${DateUtils.getCurrentTime()}\t${maxTempStr}\t${value}\t${vivoTempStr}"
                            FileOutputUtil.writeTextToFile(fileName, content)
                        }
                        dialog.dismiss()
                    }
                }).show()
        }

        /*退出页面*/
        mBinding.btnCloseOff.setOnClickListener {
            replaceFragment(
                activity,
                (activity as MainActivity).getFragmentContainerId(),
                DeskTopFragment(),
                this@StartMonitoringFragment,
                null,
                true
            )
        }

        /*录屏按钮点击*/
        mBinding.ivVideotape.click {
            /*第二种 整屏幕录制*/
            if (mViewModel.isRecord.value == false) {
                mViewModel.setIsRecord(true)
                val captureIntent = mMediaProjectionManager?.createScreenCaptureIntent()
                recordLauncher.launch(captureIntent)
            } else {
                mViewModel.setIsRecord(false)
            }
        }

        /*弹窗事件监听*/
        warningDialog.setOnDismissListener {
            pauseWarningAndAlarmAnimation()
            if (warningDialog.getWarningType().isNullOrEmpty()) return@setOnDismissListener
            warningAndAlarmTimeStamps[warningDialog.getWarningType()] =
                DateUtils.getCurrentTimeStamp()
        }
        alarmDialog.setOnDismissListener {
            pauseWarningAndAlarmAnimation()
            if (alarmDialog.getAlarmType().isNullOrEmpty()) return@setOnDismissListener
            warningAndAlarmTimeStamps[alarmDialog.getAlarmType()] = DateUtils.getCurrentTimeStamp()
        }
    }

    /**
     * 初始化观察者
     */
    private fun initObserver() {
        mViewModel.petInfoEntity.observe(this) {
            mBinding.tvWeight.text =
                "${it.weight} ${resources.getStringArray(com.axend.lib_base.R.array.app_weight_unit)[it.weightUnit]}"

            initLineChart(
                hrChartData,
                mBinding.lineChartHr,
                com.axend.lib_base.R.color.green_level_2,
                (it.heartAlarmLimit
                    ?: getDefaultThresholdType(getSpeciesType(it.species)).heartAlarmUpLimit).roundToFloatOneDecimal(),
                (it.heartAlarmLower
                    ?: getDefaultThresholdType(getSpeciesType(it.species)).heartAlarmLowLimit).roundToFloatOneDecimal()
            )

            initLineChart(
                rrChartData,
                mBinding.lineChartRr,
                com.axend.lib_base.R.color.blue_level_2,
                (it.breathAlarmLimit
                    ?: getDefaultThresholdType(getSpeciesType(it.species)).breathUpLimit).roundToFloatOneDecimal(),
                (it.breathAlarmLower
                    ?: getDefaultThresholdType(getSpeciesType(it.species)).breathLowLimit).roundToFloatOneDecimal()
            )
            initLineChart(
                tmpChartData,
                mBinding.lineChartTf,
                com.axend.lib_base.R.color.yellow_level_2,
                (it.tempAlarmLimit ?: getTempType(
                    getSpeciesType(it.species),
                    it.temperatureUnit
                ).temperatureUpLimit).roundToFloatOneDecimal(),
                (it.tempAlarmLower ?: getTempType(
                    getSpeciesType(it.species),
                    it.temperatureUnit
                ).temperatureLowLimit).roundToFloatOneDecimal()
            )

            initLineChart(
                hrEcgChartData,
                mBinding.lineEcgChartHr,
                com.axend.lib_base.R.color.green_level_2,
                140f,
                50f
            )

            initLineChart(
                rrEcgChartData,
                mBinding.lineEcgChartRr,
                com.axend.lib_base.R.color.blue_level_2,
                35f,
                8f
            )

            /*心率*/
            mBinding.tvHrMaxValue.text = (it.heartAlarmLimit ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).heartAlarmUpLimit).roundToOneDecimalPlace()
            mBinding.tvHrMiddleValueOne.text = (it.heartWarningLimit ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).heartWarningUpLimit).roundToOneDecimalPlace()
            mBinding.tvHrMiddleValueTwo.text = (it.heartWarningLower ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).heartWarningLowLimit).roundToOneDecimalPlace()
            mBinding.tvHrMinValue.text = (it.heartAlarmLower ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).heartAlarmLowLimit).roundToOneDecimalPlace()
            /*呼吸*/
            mBinding.tvRrMaxValue.text = (it.breathAlarmLimit ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).breathUpLimit).roundToOneDecimalPlace()
            mBinding.tvRrMiddleValueOne.text = (it.breathWarningLimit ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).breathWarningUpLimit).roundToOneDecimalPlace()
            mBinding.tvRrMiddleValueTwo.text = (it.breathWarningLower ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).breathWarningLowLimit).roundToOneDecimalPlace()
            mBinding.tvRrMinValue.text = (it.breathAlarmLower ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).breathLowLimit).roundToOneDecimalPlace()
            /*温度*/
            mBinding.tvTfMaxValue.text = (it.tempAlarmLimit ?: getTempType(
                getSpeciesType(it.species),
                it.temperatureUnit
            ).temperatureUpLimit).roundToOneDecimalPlace()
            mBinding.tvTfMiddleValueOne.text = (it.tempWarningLimit ?: getTempType(
                getSpeciesType(it.species),
                it.temperatureUnit
            ).temperatureWarningUpLimit).roundToOneDecimalPlace()
            mBinding.tvTfMiddleValueTwo.text = (it.tempWarningLower ?: getTempType(
                getSpeciesType(it.species),
                it.temperatureUnit
            ).temperatureWarningLowLimit).roundToOneDecimalPlace()
            mBinding.tvTfMinValue.text = (it.tempAlarmLower ?: getTempType(
                getSpeciesType(it.species),
                it.temperatureUnit
            ).temperatureLowLimit).roundToOneDecimalPlace()

            /*折线图 心率*/
            mBinding.tvHrBrokenMaxValue.text = (it.heartAlarmLimit ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).heartAlarmUpLimit).roundToOneDecimalPlace()
            mBinding.tvHrBrokenMinValue.text = (it.heartAlarmLower ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).heartAlarmLowLimit).roundToOneDecimalPlace()
            /*折线图 呼吸*/
            mBinding.tvRrBrokenMaxValue.text = (it.breathAlarmLimit ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).breathUpLimit).roundToOneDecimalPlace()
            mBinding.tvRrBrokenMinValue.text = (it.breathAlarmLower ?: getDefaultThresholdType(
                getSpeciesType(it.species)
            ).breathLowLimit).roundToOneDecimalPlace()
            /*折线图 温度*/
            mBinding.tvTfBrokenMaxValue.text = (it.tempAlarmLimit ?: getTempType(
                getSpeciesType(it.species),
                it.temperatureUnit
            ).temperatureUpLimit).roundToOneDecimalPlace()
            mBinding.tvTfBrokenMinValue.text = (it.tempAlarmLower ?: getTempType(
                getSpeciesType(it.species),
                it.temperatureUnit
            ).temperatureLowLimit).roundToOneDecimalPlace()

        }
        /*温度观察*/
        mViewModel.bodyMaxTemp.observe(this) {
            updateEntry(
                tmpChartData,
                tmpDashList,
                mBinding.lineChartTf,
                it.toFloatOrDefault(0f),
                com.axend.lib_base.R.color.yellow_level_2,
                lineDataMode
            )

            if (it.toFloatOrNull() == null) return@observe
            checkFaceMoveAndTempAlarm(
                it.toFloatOrDefault(0f),
                mViewModel.petInfoEntity.value?.tempAlarmLimit ?: TempType.getTempType(
                    getSpeciesType(petInfoEntity?.species!!),
                    petInfoEntity?.temperatureUnit!!
                ).temperatureUpLimit,
                mViewModel.petInfoEntity.value?.tempAlarmLower ?: TempType.getTempType(
                    getSpeciesType(petInfoEntity?.species!!),
                    petInfoEntity?.temperatureUnit!!
                ).temperatureLowLimit,
                mViewModel.petInfoEntity.value?.tempWarningLimit ?: TempType.getTempType(
                    getSpeciesType(petInfoEntity?.species!!),
                    petInfoEntity?.temperatureUnit!!
                ).temperatureWarningUpLimit,
                mViewModel.petInfoEntity.value?.tempWarningLower ?: TempType.getTempType(
                    getSpeciesType(petInfoEntity?.species!!),
                    petInfoEntity?.temperatureUnit!!
                ).temperatureWarningLowLimit,
                AlarmTag.TEMPERATURE_ALARM.value,
                AlarmTag.TEMPERATURE_WARNING.value,
            )
        }
        /*开始暂停*/
        mViewModel.isPause.observe(this) {
            if (it) {
                mBinding.btnPause.setImageResource(com.axend.lib_base.R.mipmap.icon_bofang)
                mBinding.btnPause.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_colorprimary)
                mBinding.cmTime.stop()
                pauseOffset = SystemClock.elapsedRealtime() - mBinding.cmTime.base
                /*暂停获取红外和雷达数据*/
                guideInterface?.stopGetImage()
                /*暂时注释 usb串口*/
//                USBTransferUtil.getInstance().disconnect()
                /*关闭otg串口*/
                SerialManage.getInstance().colse()
                stopEcgChartTimer()
            } else {
                mBinding.btnPause.setImageResource(com.axend.lib_base.R.mipmap.icon_zanting)
                mBinding.btnPause.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_yellow)
                mBinding.cmTime.base = SystemClock.elapsedRealtime() - pauseOffset
                mBinding.cmTime.start()
                /*开始获取红外和雷达数据*/
                guideInterface?.startGetImage(setImageCallBackInterface())
//                USBTransferUtil.getInstance().connect()
                //打开串口
                SerialManage.getInstance().open(true)
                if (mViewModel.isShowCurve.value == false) {
                    startEcgChart()
                }
            }
        }
        /*呼吸频率*/
        mViewModel.breathRate.observe(this) {
            if (mViewModel.isShowCurve.value == true) {
                updateEntry(
                    rrChartData,
                    rrDashList,
                    mBinding.lineChartRr,
                    it.toFloatOrDefault(0f),
                    com.axend.lib_base.R.color.blue_level_2,
                    lineDataMode
                )
            }

            if (it.toFloatOrNull() == null) return@observe
            checkAlarmAndWarn(
                it.toFloatOrDefault(0f),
                mViewModel.petInfoEntity.value?.breathAlarmLimit ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).breathUpLimit,
                mViewModel.petInfoEntity.value?.breathAlarmLower ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).breathLowLimit,
                mViewModel.petInfoEntity.value?.breathWarningLimit ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).breathWarningUpLimit,
                mViewModel.petInfoEntity.value?.breathWarningLower ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).breathWarningLowLimit,
                com.axend.lib_base.R.string.app_abnormal_respiratory,
                AlarmTag.BREATH_ALARM.value,
                AlarmTag.BREATH_WARNING.value
            )
        }
        /*呼吸频率ecg*/
        mViewModel.breathRateEcg.observe(this) {
            if (mViewModel.isShowCurve.value == false) {
                ChartHelper.isStartBreathEcg = true
                ChartHelper.breathYValue = it.toFloatOrDefault(0f)
                if (it.toFloatOrDefault(0f).roundToInt() != 0) {
                    ChartHelper.breathTimeMillis =
                        (6000 / it.toFloatOrDefault(0f).roundToInt()).toLong()
//                    Log.d("breathTimeMillis",ChartHelper.breathTimeMillis.toString())
                }
            }
        }
        /*心率*/
        mViewModel.heartRate.observe(this) {
            if (mViewModel.isShowCurve.value == true) {
                updateEntry(
                    hrChartData,
                    hrDashList,
                    mBinding.lineChartHr,
                    it.toFloatOrDefault(0f),
                    com.axend.lib_base.R.color.green_level_2,
                    lineDataMode
                )
            }

            if (it.toFloatOrNull() == null) return@observe
            checkAlarmAndWarn(
                it.toFloatOrDefault(0f),
                mViewModel.petInfoEntity.value?.heartAlarmLimit ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).heartAlarmUpLimit,
                mViewModel.petInfoEntity.value?.heartAlarmLower ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).heartAlarmLowLimit,
                mViewModel.petInfoEntity.value?.heartWarningLimit ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).heartWarningUpLimit,
                mViewModel.petInfoEntity.value?.heartWarningLower ?: getDefaultThresholdType(
                    getSpeciesType(petInfoEntity?.species!!)
                ).heartWarningLowLimit,
                com.axend.lib_base.R.string.app_abnormal_heart,
                AlarmTag.HEART_RATE_ALARM.value,
                AlarmTag.HEART_RATE_WARNING.value
            )
        }
        /*心率ecg*/
        mViewModel.heartRateEcg.observe(this) {
            if (mViewModel.isShowCurve.value == false) {
                ChartHelper.isStartHeartEcg = true
                ChartHelper.heartYValue = it.toFloatOrDefault(0f)
                if (it.toFloatOrDefault(0f).roundToInt() > 0) {
                    ChartHelper.heartTimeMillis =
                        (6000 / it.toFloatOrDefault(0f).roundToInt()).toLong()
//                    Log.d("breathTimeMillis",ChartHelper.breathTimeMillis.toString())
                }
            }
        }
        /*雷达距离*/
        mViewModel.distance.observe(this) {
            mBinding.tvRadarDistance.text = "$it"
        }
        /*图表切换*/
        mViewModel.isShowCurve.observe(this) {
//            if (!it && mViewModel.isPause.value == false) {
//                startEcgChart()
//            } else {
//                stopEcgChartTimer()
//            }
        }
        /*报警开关*/
        mViewModel.isAlarm.observe(this) {
            if (it) {
                mBinding.btnBell.setImageResource(com.axend.lib_base.R.mipmap.icon_unmute)
                mBinding.btnBell.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_colorprimary)
            } else {
                mBinding.btnBell.setImageResource(com.axend.lib_base.R.mipmap.icon_bell)
                mBinding.btnBell.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_gray)
            }
        }
        /*体动*/
        mViewModel.isMove.observe(this) {
            if (mViewModel.petInfoEntity.value?.alarmSetting!! == 0 && mViewModel.isAlarm.value!!) {
                if (it) {
                    // 获取或创建对应警告类型的计数器
                    val counter = warningCounters.getOrPut(AlarmTag.MOVE_WARNING.value) {
                        WarningCounter(
                            AlarmTag.MOVE_WARNING.value,
                            0
                        )
                    }
                    counter.count++ // 增加计数器
                    if (counter.count >= 5) {
                        if (warningAndAlarmTimeStamps[AlarmTag.MOVE_WARNING.value] == null) {
                            warningDialog.show(
                                getString(com.axend.lib_base.R.string.app_abnormal_body_movement),
                                AlarmTag.MOVE_WARNING.value
                            )
                        } else {
                            if (DateUtils.isTimeStampGreaterThan(warningAndAlarmTimeStamps[AlarmTag.MOVE_WARNING.value]!!)) {
                                warningDialog.show(
                                    getString(com.axend.lib_base.R.string.app_abnormal_body_movement),
                                    AlarmTag.MOVE_WARNING.value
                                )
                            }
                        }
                        counter.count = 0
                        lifecycleScope.launch(Dispatchers.IO) {
                            FileOutputUtil.saveWarningData("${DateUtils.getCurrentTime()}\t${AlarmTag.MOVE_WARNING.value}\t${bodyMoveFloat}\r\n")
                        }
                    }
                } else {
                    if (warningDialog.isShowing && warningDialog.getWarningType() == AlarmTag.MOVE_WARNING.value) {
                        warningDialog.dismiss()
                        warningCounters.remove(AlarmTag.MOVE_WARNING.value)
                    }
                }
            }
        }
        /*是否离线*/
        mViewModel.isDisconnect.observe(this) {
            if (it) {
                mViewModel.setBreathRate("0")
                mViewModel.setHeartRate("0")
                mViewModel.setHeartRateEcg("0")
                mViewModel.setBreathRateEcg("0")
                disconnectDialog.show()
            } else {
                if (disconnectDialog.isShowing) disconnectDialog.dismiss()
            }
        }

        /*录屏*/
        mViewModel.isRecord.observe(this) {
            try {
                if (it) {
                    /*第一种 录制原始红外 暂时注释*/
//                    val fileName =
//                        "${Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)}${File.separator}video_${DateUtils.getCurrentTime("yyyy-MM-dd-HH-mm-ss")}.mp4"
//                    bitmapToVideo?.startRecording(fileName)

                } else {
                    videoAnimation.cancel()
                    mBinding.llShowVideo.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_colorprimary)
                    mBinding.btnShowVideo.setImageResource(com.axend.lib_base.R.drawable.icon_back)
                    mBinding.btnShowVideo.visibility = View.VISIBLE
                    mBinding.ivVideotape.setImageResource(com.axend.lib_base.R.mipmap.icon_luping)
                    mBinding.cmVideotapeTime.visibility = View.GONE
                    mBinding.cmVideotapeTime.stop()
                    stopScreenRecordingService()
                    /*暂时注释第二种 录制原始红外*/
//                    bitmapToVideo?.stopRecording()
                }
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        /*系统当前时间 美标准时间*/
        lifecycleScope.launch {
            flow {
                while (true) {
                    emit(getCurrentDateTime())
                    delay(1.seconds)
                }
            }.collectLatest { formattedTime ->
                withContext(Dispatchers.Main) {
                    mBinding.tvTime.text = formattedTime
                }
            }
        }
        /*api30调用startActivityForResult*/
        recordLauncher = registerForActivityResult(
            ActivityResultContracts.StartActivityForResult()
        ) { result ->
            if (result.resultCode == Activity.RESULT_OK) {
                try {
                    val service = Intent(requireContext(), ScreenRecordService::class.java).apply {
                        putExtra("resultCode", result.resultCode)
                        putExtra("data", result.data)
                    }

                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        requireActivity().startForegroundService(service)
                    } else {
                        requireActivity().startService(service)
                    }
                    mViewModel.setIsRecord(true)
                    mBinding.llShowVideo.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_white)
                    mBinding.btnShowVideo.setImageResource(com.axend.lib_base.R.mipmap.icon_lupingkaishi)
                    videoAnimation.start()
                    mBinding.ivVideotape.setImageResource(com.axend.lib_base.R.mipmap.icon_lupingkaishi)
                    mBinding.cmVideotapeTime.visibility = View.VISIBLE
                    // 开始计时
                    mBinding.cmVideotapeTime.apply {
                        setOnChronometerTickListener {
                            // 计算已过时间
                            val timeMillis = SystemClock.elapsedRealtime() - it.base
                            // 格式化时间
                            val formattedTime = formatTime(timeMillis)
                            // 更新Chronometer的显示文本
                            it.text = formattedTime
                        }
                        base = SystemClock.elapsedRealtime()
                        start()
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }

    }

    private fun startEcgChart() {
        /*启动心跳ecg图*/
        startHeartEcgChart(
            hrEcgChartData,
            mBinding.lineEcgChartHr,
            com.axend.lib_base.R.color.green_level_2,
            lineDataMode
        )
        /*启动呼吸ecg图*/
        updateBreathEcgChart(
            rrEcgChartData,
            mBinding.lineEcgChartRr,
            com.axend.lib_base.R.color.blue_level_2,
            lineDataMode,
        )
    }


    /**
     * 切换图表线类型
     */
    private fun switchChartLine(lineImageView: AppCompatImageView) {
        mBinding.ivChartLineBroken.setBackgroundResource(com.axend.lib_base.R.drawable.shape_stock_gray)
        mBinding.ivChartLineCurved.setBackgroundResource(com.axend.lib_base.R.drawable.shape_stock_gray)
        lineImageView.setBackgroundResource(com.axend.lib_base.R.drawable.shape_rounded_rectangle_gray)
        val paddingValue = dp2px(10f)
        mBinding.ivChartLineBroken.setPadding(
            paddingValue,
            paddingValue,
            paddingValue,
            paddingValue
        )
        mBinding.ivChartLineCurved.setPadding(
            paddingValue,
            paddingValue,
            paddingValue,
            paddingValue
        )
        when (lineImageView) {
            /*趋势图*/
            mBinding.ivChartLineBroken -> {
                lineDataMode = LineDataSet.Mode.LINEAR
                mViewModel.setIsShowCurve(false)
            }
            /*曲线*/
            mBinding.ivChartLineCurved -> {
                lineDataMode = LineDataSet.Mode.CUBIC_BEZIER
                mViewModel.setIsShowCurve(true)
            }
        }

    }


    // 时间格式化函数
    private fun formatTime(timeInMillis: Long): String {
        val hours = timeInMillis / (1000 * 60 * 60)
        val minutes = (timeInMillis % (1000 * 60 * 60)) / (1000 * 60)
        val seconds = (timeInMillis % (1000 * 60)) / 1000
        // 确保小时、分钟、秒至少显示两位数，不足则前面补0
        return String.format(Locale.getDefault(), "%02d:%02d:%02d", hours, minutes, seconds)
    }


    override fun onResume() {
        super.onResume()
        ScreenAutoAdapter.match(requireActivity(), designSize)
        startGetImage()
        mViewModel.getPetInfoById(petInfoEntity?.id!!)
        var heartStartValue =
            (if (petInfoEntity?.heartAlarmLower != null && (petInfoEntity!!.heartAlarmLower!! > 30 && petInfoEntity!!.heartAlarmLower!! < 210)) {
                (petInfoEntity?.heartAlarmLower)?.minus(10)
            } else {
                getDefaultThresholdType(
                    getSpeciesType(
                        petInfoEntity?.species!!
                    )
                ).heartAlarmLowLimit - 10
            })?.toUInt()?.toByteArray()
        var heartEndValue =
            (if (petInfoEntity?.heartAlarmLimit != null && (petInfoEntity!!.heartAlarmLimit!! > 30 && petInfoEntity!!.heartAlarmLimit!! < 210)) {
                (petInfoEntity!!.heartAlarmLimit)?.plus(10)
            } else {
                getDefaultThresholdType(
                    getSpeciesType(
                        petInfoEntity?.species!!
                    )
                ).heartAlarmUpLimit + 10
            })?.toUInt()?.toByteArray()
        SerialManage.getInstance().sendRadarCommand(
            RadarCommand(
                DataSender.TvtMessageTcpFuncE.Tvt_Msg_Tcp_Fuc_Set_heart_startFreq_Hz,
                heartStartValue!!
            )
        )
        SerialManage.getInstance().sendRadarCommand(
            RadarCommand(
                DataSender.TvtMessageTcpFuncE.Tvt_Msg_Tcp_Fuc_Set_heart_endFreq_Hz,
                heartEndValue!!
            )
        )
        /*补偿值更新后清空平滑算法集合数据*/
        if (oldTempCalibration != mViewModel.petInfoEntity.value?.tempCalibration) {
            oldTempCalibration = mViewModel.petInfoEntity.value?.tempCalibration
            maxTempCountC = 0
            maxTempCountF = 0
        }
    }


    override fun onPause() {
        super.onPause()
        stopGetImage()
        /*暂停警报*/
        pauseWarningAndAlarmAnimation()
        if (warningDialog.isShowing) warningDialog.dismiss()
        if (alarmDialog.isShowing) alarmDialog.dismiss()
//        mViewModel.setIsPause(true)
    }


    override fun onDestroyView() {
        super.onDestroyView()
        AudioPlayer.getInstance(requireContext()).stop()
        guideInterface?.guideCoreExit()
        SerialManage.getInstance().colse()
    }

    /*********红外*********/
    override fun usbConnect() {
        /*尝试重新获取数据*/
        startGetImage()
    }

    override fun usbDisConnect() {
//        toast(getString(com.axend.lib_base.R.string.app_device_disconnected))
    }

    override fun callBackOneFrameBitmap(p0: Bitmap?, p1: ShortArray?) {

        mIrSurfaceView.doDraw(p0, guideInterface?.shutterStatus!!)
        //mIrSurfaceView.doDraw(p0, guideInterface.shutterStatus)
        count++
        if (count % FRAME == 0) {
            if (mViewModel.isRecord.value == true) {
                bitmapToVideo?.addFrame(p0)
            }
            val tempArray = FloatArray(100 * 100)
            val (y16W, y16H) = when (rotateType) {
                1, 3 -> Pair(SRC_WIDTH, SRC_HEIGHT)
                else -> Pair(SRC_HEIGHT, SRC_WIDTH)
            }
            ThreadPoolUtils.getCachedThreadPool().execute {
                val bitmap = p0?.let {
                    MotionDetectHelper?.processThermalImagingTargetMotion(
                        it, callback = { value: Int, isOut: Boolean ->
                            //累加移动值
                            warningMoveList.add(isOut)
                            if (warningMoveList.size > 8) {
                                warningMoveList.removeAt(0)
                            }
                        })
                }
            }
            getOneRectTemp()
            val (rawWidth, rawHeight) = when (rotateType) {
                1, 3 -> Pair(SRC_WIDTH, SRC_HEIGHT)
                else -> Pair(SRC_HEIGHT, SRC_WIDTH)
            }
            val centerIndex = rawWidth * (rawHeight / 2) + rawWidth / 2
            mY16Frame = p1
            //温度显示算法二
            filteredMaxTempStr = tempMeasure.finalOutWithFile(
                maxTempArray,
                vivoMaxTemp!!
            )
            if (mViewModel.petInfoEntity.value?.temperatureUnit == 0) {
                mViewModel.setBodyMaxTemp(
                    (filteredMaxTempStr.toFloatOrDefault(0f) + mViewModel.petInfoEntity.value?.tempCalibration!!).celsiusToFahrenheit()
                        .roundToOneDecimalPlace()
                )
            } else {
                mViewModel.setBodyMaxTemp(
                    (filteredMaxTempStr.toFloatOrDefault(0f) + mViewModel.petInfoEntity.value?.tempCalibration!!).roundToOneDecimalPlace()
                )
            }
            var content =
                "${DateUtils.getCurrentTime()}\t${filteredMaxTempStr}\t${vivoMaxTemp}\t${maxTempArray}\r\n"
            FileOutputUtil.saveMoveTempData(moveTempFileName, content)

            runOnUIThread {
//                mBinding.tvDebugText.visibility = View.VISIBLE
//                mBinding.tvDebugText.text = "当前监测值：${
//                    filteredMaxTempStr.toFloatOrDefault(0f).roundToOneDecimalPlace()
//                }\tvivoMaxTemp:${vivoMaxTemp}\tbodyMaxTemp:${maxTempStr}"

                mBinding.flDisplay.removeView(mHighCrossView)

                val scale = irSurfaceViewWidth / y16W
                val lp = FrameLayout.LayoutParams(highCrossWidth, highCrossHeight).apply {
                    leftMargin = ((maxX * scale) - highCrossWidth / 2).toInt()
                    topMargin = ((maxY * scale) - highCrossHeight / 2).toInt()
                }

                mBinding.flDisplay.addView(mHighCrossView, lp)

                /*绘制矩形到Layout上*/
                mBinding.flDisplay.removeView(rectangleView)
                rectangleView.setRectangleProperties(
                    centerX,
                    centerY,
                    radius * 2,
                    radius * 2,
                    scale
                )
                mBinding.flDisplay.addView(rectangleView)
            }

            count = 0
        }
        lifecycleScope.launch(Dispatchers.IO) {
            var content = "${DateUtils.getCurrentTime("yyyy-MM-dd HH:mm:ss:SSS")}" +
                    "\t${guideInterface?.foucsTemp}\t${guideInterface?.shutterTemp}\t${guideInterface?.envTemp}\t${guideInterface?.centerTemp}" +
                    "\t${
                        guideInterface?.centerTemp?.let {
                            guideInterface?.getHumanTemp(
                                it.toFloatOrDefault(
                                    0f
                                ), GuideInterface.DEFAULT_AMBIENT_TEMP
                            )
                        }
                    }" +
                    "\t${maxTempStr}\t${
                        guideInterface?.getHumanTemp(
                            maxTempStr.toFloatOrDefault(0f),
                            GuideInterface.DEFAULT_AMBIENT_TEMP
                        )
                    }\t${filteredMaxTempStr}" +
                    "\t${if (guideInterface?.isCalTempOk!!) "stable" else "unstable"}" +
                    "\t${maxX}\t${maxY}\r\n"
            FileOutputUtil.saveTempData(generalTempFileName, content)
        }
    }


    /*体表最高温连读升高或者下降超过2.5度，持续5个数据（3秒），将过滤温度窗口数据清除*/
    private fun tempChangeDetect(targetTemp: Float, tempDiff: Float) {
        /*2024-11-22：让温度快速回升或者降落*/
        var tempDiff = tempDiff
        if (mViewModel.petInfoEntity.value?.temperatureUnit == 0) {
            tempDiff *= 1.8f
        } else {
            tempDiff = 2.5f
        }
        if (Math.abs(filteredMaxTemp - targetTemp) >= tempDiff) {
            keepCount += 1
        } else {
            keepCount = 0
        }
        if (keepCount >= keepCountThreshold) {
            maxTempCountC = 0
            maxTempCountF = 0
            keepCount = 0 // 重置计数器
        }
    }

    private fun loadLocalImage(imagePath: String, imageView: ImageView) {
        val file = File(imagePath)

        if (file.exists()) {
            val bitmap = BitmapFactory.decodeFile(file.absolutePath)
            if (bitmap != null) {
                imageView.setImageBitmap(bitmap)
            } else {
                Log.e("Start", "Failed to decode image from path: $imagePath")
            }
        } else {
            Log.e("Start", "File does not exist at path: $imagePath")
        }
    }

    /*********Radar Data*********/
    override fun onReceive(data: ByteArray?) {
        /*50ms一次*/
        if (data?.size != 52) return // 确保数据有效且大小正确

        /*呼吸频率*/
        val breathing = data.copyOfRange(16, 20)
        val breathInt = ByteBuffer.wrap(breathing).int
        val breathFloat = intBitsToFloat(breathInt)

        /*心率*/
        val hearting = data.copyOfRange(24, 28)
        val heartInt = ByteBuffer.wrap(hearting).int
        val heartFloat = intBitsToFloat(heartInt)

        /*体动*/
        val bodyMove = data.copyOfRange(44, 48)
        val bodyMoveInt = ByteBuffer.wrap(bodyMove).int
        val bodyMoveFloat = intBitsToFloat(bodyMoveInt)

        /*距离*/
        val distance = data.copyOfRange(32, 36)
        val distanceInt = ByteBuffer.wrap(distance).int
        val distanceFloat = intBitsToFloat(distanceInt)

        // 当计数达到20时，更新ViewModel并重置计数器
        if (++radarDataCount == 20) {
            mViewModel.setBreathRate(breathFloat.roundToNearestInteger().toString())
            mViewModel.setHeartRate(heartFloat.roundToNearestInteger().toString())
            mViewModel.setIsMove(bodyMoveFloat > 50)
            mViewModel.setDistance(
                if (mViewModel.petInfoEntity.value?.lengthUnit == 0) distanceFloat.mToCm()
                    .roundToNearestInteger().toString() else distanceFloat.mToIn()
                    .roundToNearestInteger().toString()
            )

//            mViewModel.setIsMove(bodyMoveFloat > 0)
            radarDataCount = 0
        }
        //ecg图表更新模式
        if (mViewModel.isShowCurve.value == false && ++radarDataCountEcg == 80) {
            mViewModel.setBreathRateEcg(breathFloat.roundToNearestInteger().toString())
            mViewModel.setHeartRateEcg(heartFloat.roundToNearestInteger().toString())
            radarDataCountEcg = 0
        }
    }

    override fun onError(errorCode: Int) {

    }


    /**************otg radar data *************/
    override fun connectMsg(path: String?, isSucc: Boolean) {
        mViewModel.setIsDisconnect(!isSucc)
    }

    override fun readData(path: String?, data: ByteArray?, size: Int) {
        if (data!![13].toInt() == 38) {
//            Log.e("串口数据回调", "串口 $path -获取数据$data")
            /*呼吸频率*/
            val breathing = data.copyOfRange(16, 20)
            val breathInt = ByteBuffer.wrap(breathing).int
            val breathFloat = intBitsToFloat(breathInt)

            val outputFilterBreathOut = data.copyOfRange(20, 24)
            val outputFilterBreathOutInt = ByteBuffer.wrap(outputFilterBreathOut).int
            val outputFilterBreathOutFloat = intBitsToFloat(outputFilterBreathOutInt)

            /*心率*/
            val hearting = data.copyOfRange(24, 28)
            val heartInt = ByteBuffer.wrap(hearting).int
            val heartFloat = intBitsToFloat(heartInt)

            val outputFilterHeartOut = data.copyOfRange(28, 32)
            val outputFilterHeartOutInt = ByteBuffer.wrap(outputFilterHeartOut).int
            val outputFilterHeartOutFloat = intBitsToFloat(outputFilterHeartOutInt)

            val objSignal = ByteArray(4)
            System.arraycopy(data, 36, objSignal, 0, 4)
            val objSignalInt = ByteBuffer.wrap(objSignal).int
            val objSignalFloat = intBitsToFloat(objSignalInt)

            val sleepStage = ByteArray(4)
            System.arraycopy(data, 40, sleepStage, 0, 4)
            val sleepStageInt = ByteBuffer.wrap(sleepStage).int
            val sleepStageFloat = intBitsToFloat(sleepStageInt)

            /*体动*/
            val bodyMove = data.copyOfRange(44, 48)
            val bodyMoveInt = ByteBuffer.wrap(bodyMove).int
            val bodyMoveFloat = intBitsToFloat(bodyMoveInt)

            val bodyMoveRange = ByteArray(4)
            System.arraycopy(data, 48, bodyMoveRange, 0, 4)
            val bodyMoveRangeInt = ByteBuffer.wrap(bodyMoveRange).int
            val bodyMoveRangeFloat = intBitsToFloat(bodyMoveRangeInt)

            /*距离*/
            val distance = data.copyOfRange(32, 36)
            val distanceInt = ByteBuffer.wrap(distance).int
            val distanceFloat = intBitsToFloat(distanceInt)
            /*时间*/
            val time = DateUtils.getCurrentTime("yyyy-MM-dd HH:mm:ss:SSS")
            /*日志记录*/
            FileOutputUtil.addRadarData(
                RadarData(
                    breathFloat.toPlainStringNoRounding(),
                    outputFilterBreathOutFloat.toPlainStringNoRoundingSix(),
                    heartFloat.toPlainStringNoRounding(),
                    outputFilterHeartOutFloat.toPlainStringNoRoundingSix(),
                    distanceFloat.roundToOneDecimalPlace(),
                    objSignalFloat.toPlainStringNoRoundingSix(),
                    sleepStageFloat.roundToNoDecimalPlaces(),
                    bodyMoveFloat.toPlainStringNoRoundingSix(),
                    bodyMoveRangeFloat.toPlainStringNoRounding(),
                    time
                )
            )
            FileOutputUtil.addRadarBpmData(
                RadarBpmData(
                    breathFloat.toPlainStringNoRounding(),
                    heartFloat.toPlainStringNoRounding(),
                    time
                )
            )
            // 当计数达到20时，更新ViewModel并重置计数器
            if (++radarDataCount >= 20) {
                val breathRateInt = breathFloat.roundToNearestInteger()
                val heartRateInt = heartFloat.roundToNearestInteger()
                val breathRateEcg = breathFloat.roundToFloatOneDecimal()
                val heartRateEcg = heartFloat.roundToFloatOneDecimal()
                val distance = if (mViewModel.petInfoEntity.value?.lengthUnit == 0) {
                    distanceFloat.mToCm().roundToFloatOneDecimal()
                } else {
                    distanceFloat.mToIn().roundToFloatOneDecimal()
                }

                // 确保数值在合理的范围内
                if (breathRateInt <= 16777215 && heartRateInt <= 16777215) {
                    mViewModel.setBreathRate(breathRateInt.toString())
                    mViewModel.setHeartRate(heartRateInt.toString())
                    mViewModel.setBreathRateEcg(breathRateEcg.toString())
                    mViewModel.setHeartRateEcg(heartRateEcg.toString())
                    this.bodyMoveFloat = bodyMoveFloat
                    mViewModel.setIsMove(bodyMoveFloat > 70)
                    mViewModel.setDistance(distance.toString())
                } else {
                    // 处理超出范围的情况
                    Log.e("StartMonitoringFragment", "Breath rate or heart rate exceeds the maximum integer value")
                }
                radarDataCount = 0


//                mViewModel.setIsMove(bodyMoveFloat > 0)
            }
            //ecg图表更新模式
//            if (++radarDataCountEcg == 20) {
//
//                radarDataCountEcg = 0
//            }
        }
    }


    override fun writeData(): RadarUpBean {
        return RadarUpBean(null, false, readVersion = false)
    }

    override fun radarVersion(bytes: ByteArray?) {
        val result: String = byteArrayToCommaSeparatedString(bytes!!)
        Log.d("RadarVersion0", result)
        val Version = "version$result"
        Log.d("RadarVersion1", Version)
    }

    override fun updata_button_click(): Boolean {
        return false
    }

    override fun progress(progress: Int, total: Int) {

    }

//    override fun onError(errorCode: Int) {
//        when (errorCode) {
//            ERROR_CODE_NO_PERMISSION -> {
//                toast(getString(com.axend.lib_base.R.string.app_tips_permission_fail))
//            }
//
//            ERROR_CODE_DISCONNECT -> {
//                toast(getString(com.axend.lib_base.R.string.app_device_connect_tips))
//            }
//
//            ERROR_CODE_NO_DEVICE -> {
//                toast(getString(com.axend.lib_base.R.string.app_device_connect_tips))
//            }
//        }
//    }

    /*********相机Camera old api*********/
    // 开始相机预览
//    private fun startCameraPreview() {
//        surfaceHolder = mBinding.finalCameraSurfaceView.holder
//        surfaceHolder.addCallback(object : SurfaceHolder.Callback {
//            override fun surfaceCreated(holder: SurfaceHolder) {
//                XXPermissions.with(requireActivity())
//                    .permission(Permission.CAMERA)
//                    .permission(Permission.ACCESS_COARSE_LOCATION)
//                    .request(object : OnPermissionCallback {
//                        override fun onGranted(
//                            permissions: MutableList<String>,
//                            allGranted: Boolean
//                        ) {
//                            try {
//                                camera = Camera.open()
//                            } catch (e: Exception) {
//                                e.printStackTrace()
//                            }
//                        }
//
//                        override fun onDenied(
//                            permissions: MutableList<String>,
//                            doNotAskAgain: Boolean
//                        ) {
//                            if (doNotAskAgain) {
//                                toast(getString(com.axend.lib_base.R.string.app_tips_permission_grant))
//                                XXPermissions.startPermissionActivity(
//                                    requireActivity(),
//                                    permissions
//                                )
//                            } else {
//                                toast(getString(com.axend.lib_base.R.string.app_tips_permission_fail))
//                            }
//                        }
//                    })
//            }
//
//            override fun surfaceChanged(
//                holder: SurfaceHolder,
//                format: Int,
//                width: Int,
//                height: Int
//            ) {
//                camera?.let { camera ->
//                    try {
//                        camera.stopPreview()
//                    } catch (e: Exception) {
//                        Log.e("CameraActivity", "Error stopping camera preview: ${e.message}")
//                    }
//
//                    try {
//
//                        camera.parameters = camera.parameters.apply {
//                            setRotation(90)
//                        }
//                        camera.setPreviewDisplay(holder)
//                        camera.startPreview()
//                    } catch (e: Exception) {
//                        Log.e("CameraActivity", "Error starting camera preview: ${e.message}")
//                    }
//                }
//            }
//
//            override fun surfaceDestroyed(p0: SurfaceHolder) {
//                stopCameraPreview()
//            }
//        })
//    }


    // 停止相机预览
//    private fun stopCameraPreview() {
//        camera?.let {
//            it.stopPreview()
//            it.release()
//            camera = null // 确保引用被清除，避免内存泄漏
//        }
//    }


    /*********相机CameraX*********/
    private fun startCameraPreview(
        context: Context,
        lifecycleOwner: LifecycleOwner,
        textureView: TextureView
    ) {

        /*请求相机权限*/
        XXPermissions.with(requireActivity()).permission(Permission.CAMERA)
            .permission(Permission.ACCESS_COARSE_LOCATION)
            .request(object : OnPermissionCallback {
                override fun onGranted(permissions: MutableList<String>, allGranted: Boolean) {
                    // 创建预览构建器并设置目标旋转
                    val previewBuilder = Preview.Builder()
                        .setTargetRotation(textureView.display.rotation)
                        .setResolutionSelector(
                            ResolutionSelector.Builder().setResolutionStrategy(
                                ResolutionStrategy(
                                    Size(1920, 1080),
                                    ResolutionStrategy.FALLBACK_RULE_NONE
                                )
                            ).build()
                        )

                    // 构建预览实例
                    val preview = previewBuilder.build()

                    // 设置预览视图
                    preview.setSurfaceProvider(
                        ContextCompat.getMainExecutor(requireContext())
                    ) {
                        it.provideSurface(
                            Surface(textureView.surfaceTexture),
                            ContextCompat.getMainExecutor(requireContext())
                        ) { it ->

                            if (it.surface == null) {
                                Log.e(
                                    this@StartMonitoringFragment::class.simpleName,
                                    "Surface is null"
                                )
                                return@provideSurface
                            }

                        }
                    }

                    // 获取相机提供者
                    val cameraProviderFuture = ProcessCameraProvider.getInstance(context)

                    cameraProviderFuture.addListener({
                        cameraProvider = cameraProviderFuture.get()

                        // 选择后置摄像头
                        val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA

                        // 将预览与生命周期所有者绑定
                        cameraProvider?.unbindAll()
                        val camera: androidx.camera.core.Camera? =
                            cameraProvider?.bindToLifecycle(lifecycleOwner, cameraSelector, preview)
                        // 获取 CameraControl
                        val cameraControl = camera?.cameraControl
                        // 设置曝光补偿
                        cameraControl?.setExposureCompensationIndex(+4)
                    }, ContextCompat.getMainExecutor(context))
                }

                override fun onDenied(permissions: MutableList<String>, doNotAskAgain: Boolean) {
                    if (doNotAskAgain) {
                        toast(getString(com.axend.lib_base.R.string.app_tips_permission_grant))
                        XXPermissions.startPermissionActivity(requireActivity(), permissions)
                    } else {
                        toast(getString(com.axend.lib_base.R.string.app_tips_permission_fail))
                    }
                }

            })


    }


    private fun stopCameraPreview() {
        cameraProvider?.unbindAll()
    }


    /**
     * 检查观察值是否超出警戒或警告范围，并根据次数限制显示对话框。
     *
     * @param observeValue 观察到的值
     * @param alarmLimitValue 报警上限值
     * @param alarmLowerValue 报警下限值
     * @param warningLimitValue 警告上限值
     * @param warningLowerValue 警告下限值
     * @param messageResId 对话框消息资源ID
     * @param warningType 警告类型，用于区分不同的警告计数器
     * @param triggerCount 触发警告对话框前的次数阈值，默认为30
     */
    private fun checkAlarmAndWarn(
        observeValue: Float = 0f,
        alarmLimitValue: Float?,
        alarmLowerValue: Float?,
        warningLimitValue: Float?,
        warningLowerValue: Float?,
        messageResId: Int,
        alarmType: String,
        warningType: String,
        triggerCount: Int = 30,
    ) {
        val isAlarm = mViewModel.isAlarm.value ?: return  // 如果 isAlarm 为 null，则直接返回
        if (alarmLimitValue == null || alarmLowerValue == null || warningLimitValue == null || warningLowerValue == null
            || !isAlarm
        ) {

            return
        }

        if (observeValue > alarmLimitValue || observeValue < alarmLowerValue) {
            // 获取或创建对应警告类型的计数器
            val counter = warningCounters.getOrPut(alarmType) { WarningCounter(alarmType, 0) }
            counter.count++ // 增加计数器
            if (counter.count >= triggerCount) {
                // 当计数器达到指定次数时
                warningDialog.dismiss()
                alarmDialog.show(
                    getString(
                        com.axend.lib_base.R.string.app_abnormal,
                        getString(messageResId)
                    ),
                    alarmType
                )
                when (alarmType) {
                    AlarmTag.BREATH_ALARM.value -> {
                        mBinding.ivRrAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_red)
                        mBinding.ivRrAlarmWarning.visibility = View.VISIBLE
                        rrBlinkAnimation.start()
                    }

                    AlarmTag.HEART_RATE_ALARM.value -> {
                        mBinding.ivHrAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_red)
                        mBinding.ivHrAlarmWarning.visibility = View.VISIBLE
                        hrBlinkAnimation.start()
                    }
                }
                counter.count = 0 // 重置计数器
                lifecycleScope.launch(Dispatchers.IO) {
                    FileOutputUtil.saveWarningData("${DateUtils.getCurrentTime()}\t${alarmType}\t${observeValue}\t${alarmLimitValue}\t${alarmLowerValue}\r\n")
                }
            }
        } else if (observeValue > warningLimitValue || observeValue < warningLowerValue) {
            // 获取或创建对应警告类型的计数器
            val counter = warningCounters.getOrPut(warningType) { WarningCounter(warningType, 0) }
            counter.count++ // 增加计数器

            if (counter.count >= triggerCount) { // 当计数器达到指定次数时
                if (alarmDialog.isShowing)alarmDialog.dismiss()
                warningDialog.show(
                    getString(
                        com.axend.lib_base.R.string.app_abnormal,
                        getString(messageResId)
                    ),
                    warningType
                )
                when (warningType) {
                    AlarmTag.BREATH_WARNING.value -> {
                        mBinding.ivRrAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_yellow)
                        mBinding.ivRrAlarmWarning.visibility = View.VISIBLE
                        /*警告报警为6秒后自动取消*/
                        rrBlinkAnimation.apply {
                            duration = 500
                            repeatCount = 12
                            start()
                        }
                    }

                    AlarmTag.HEART_RATE_WARNING.value -> {
                        mBinding.ivHrAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_yellow)
                        mBinding.ivHrAlarmWarning.visibility = View.VISIBLE
                        /*警告报警为6秒后自动取消*/
                        hrBlinkAnimation.apply {
                            duration = 500
                            repeatCount = 12
                            start()
                        }
                    }

                }
                counter.count = 0 // 重置计数器
                lifecycleScope.launch(Dispatchers.IO) {
                    FileOutputUtil.saveWarningData("${DateUtils.getCurrentTime()}\t${alarmType}\t${observeValue}\t${warningLimitValue}\t${warningLowerValue}")
                }
            }
        } else {
            // 当值处于正常范围时，重置当前警告计数器，并且消除当前警报
            resetWarnings(warningType, alarmType, warningDialog, alarmDialog, triggerCount)
        }
    }


    // 公共处理逻辑
    private fun handleResetAndDismiss(type: String, dialog: Dialog, triggerCount: Int) {
        if (dialog is CustomWarningDialog) {
            if (dialog.isShowing && dialog.getWarningType() == type) {
                dialog.dismiss()
                pauseWarningAndAlarmAnimation()
            }
        }
        if (dialog is CustomAlarmDialog) {
            if (dialog.isShowing && dialog.getAlarmType() == type) {
                dialog.dismiss()
                pauseWarningAndAlarmAnimation()
            }
        }

    }

    // 调用公共处理逻辑
    private fun resetWarnings(
        warningType: String,
        alarmType: String,
        warningDialog: Dialog,
        alarmDialog: Dialog,
        triggerCount: Int
    ) {
        handleResetAndDismiss(warningType, warningDialog, triggerCount)
        handleResetAndDismiss(alarmType, alarmDialog, triggerCount)
    }

    /**
     * 监测脸动和温度异常结合报警逻辑
     */
    private fun checkFaceMoveAndTempAlarm(
        observeValue: Float,
        alarmLimitValue: Float?,
        alarmLowerValue: Float?,
        warningLimitValue: Float?,
        warningLowerValue: Float?,
        alarmType: String,
        warningType: String,
        triggerCount: Int = 8
    ) {
        synchronized(this){
            val isAlarm = mViewModel.isAlarm.value ?: return  // 如果 isAlarm 为 null，则直接返回
            //温度数据
            if (alarmLimitValue != null && alarmLowerValue != null && warningLimitValue != null && warningLowerValue != null
                && isAlarm
            ) {

                if (observeValue > alarmLimitValue || observeValue < alarmLowerValue) {
                    tempAlarmList.add(true)
                } else if (observeValue > warningLimitValue || observeValue < warningLowerValue) {
                    tempWarningList.add(true)
                    tempAlarmList.add(false)
                } else {
                    tempAlarmList.add(false)
                    tempWarningList.add(false)
                }
                synchronized(tempAlarmList){if (tempAlarmList.size > triggerCount) tempAlarmList.removeAt(0)}
                synchronized(tempWarningList){if (tempWarningList.size > triggerCount) tempWarningList.removeAt(0)}


                // 判断移动列表是否所有元素都为true
                if (warningMoveList.size >= triggerCount && tempAlarmList.size >= triggerCount) {
                    // 出框异常优先
                    if (warningMoveList.all { it } && (tempAlarmList.all { it } || tempWarningList.all { it }) && petInfoEntity?.faceMoveAlarmSetting == 0) {
                        /*根据时间戳来判断是否显示*/
                        if (warningAndAlarmTimeStamps[alarmType] == null) {
                            warningDialog.show(
                                getString(
                                    com.axend.lib_base.R.string.app_abnormal,
                                    getString(com.axend.lib_base.R.string.app_abnormal_face_motion)
                                ), alarmType
                            )
                        } else {
                            if (DateUtils.isTimeStampGreaterThan(
                                    warningAndAlarmTimeStamps[alarmType]!!
                                )
                            ) {
                                warningDialog.show(
                                    getString(
                                        com.axend.lib_base.R.string.app_abnormal,
                                        getString(com.axend.lib_base.R.string.app_abnormal_face_motion)
                                    ), alarmType
                                )
                            }
                        }
                        lifecycleScope.launch(Dispatchers.IO) {
                            FileOutputUtil.saveWarningData("${DateUtils.getCurrentTime()}\t${alarmType}\t${observeValue}\t${alarmLimitValue}\t${alarmLowerValue}\r\n")
                        }
                        //否则的话直接报温度异常 温度警报优先
                    } else if (tempAlarmList.all { it }) {
                        /*根据时间戳来判断是否显示*/
                        if (warningAndAlarmTimeStamps[alarmType] == null) {
                            warningDialog.dismiss()
                            alarmDialog.show(
                                getString(
                                    com.axend.lib_base.R.string.app_abnormal,
                                    getString(com.axend.lib_base.R.string.app_abnormal_temprature)
                                ), alarmType
                            )
                            mBinding.ivTfAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_red)
                            mBinding.ivTfAlarmWarning.visibility = View.VISIBLE
                            tfBlinkAnimation.start()
                        } else {
                            if (DateUtils.isTimeStampGreaterThan(
                                    warningAndAlarmTimeStamps[alarmType]!!
                                )
                            ) {
                                warningDialog.dismiss()
                                alarmDialog.show(
                                    getString(
                                        com.axend.lib_base.R.string.app_abnormal,
                                        getString(com.axend.lib_base.R.string.app_abnormal_temprature)
                                    ), alarmType
                                )
                                mBinding.ivTfAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_red)
                                mBinding.ivTfAlarmWarning.visibility = View.VISIBLE
                                tfBlinkAnimation.start()
                            }
                        }

                        lifecycleScope.launch(Dispatchers.IO) {
                            FileOutputUtil.saveWarningData("${DateUtils.getCurrentTime()}\t${alarmType}\t${observeValue}\t${alarmLimitValue}\t${alarmLowerValue}\r\n")
                        }
                    } else if (tempWarningList.all { it }) {
                        if (alarmDialog.isShowing && alarmDialog.getAlarmType()==alarmType)return
                        if (warningAndAlarmTimeStamps[warningType] == null) {
                            warningDialog.show(
                                getString(
                                    com.axend.lib_base.R.string.app_abnormal,
                                    getString(com.axend.lib_base.R.string.app_abnormal_temprature)
                                ), warningType
                            )
                            mBinding.ivTfAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_yellow)
                            mBinding.ivTfAlarmWarning.visibility = View.VISIBLE
                            /*警告报警为6秒后自动取消*/
                            tfBlinkAnimation.apply {
                                duration = 500
                                repeatCount = 12
                                start()
                            }
                        } else {
                            if (warningAndAlarmTimeStamps[warningType] != null && DateUtils.isTimeStampGreaterThan(
                                    warningAndAlarmTimeStamps[warningType]!!
                                )
                            ) {
                                warningDialog.show(
                                    getString(
                                        com.axend.lib_base.R.string.app_abnormal,
                                        getString(com.axend.lib_base.R.string.app_abnormal_temprature)
                                    ), warningType
                                )
                                mBinding.ivTfAlarmWarning.setImageResource(com.axend.lib_base.R.mipmap.img_yichang_yellow)
                                mBinding.ivTfAlarmWarning.visibility = View.VISIBLE
                                /*警告报警为6秒后自动取消*/
                                tfBlinkAnimation.apply {
                                    duration = 500
                                    repeatCount = 12
                                    start()
                                }
                            }
                        }
                        lifecycleScope.launch(Dispatchers.IO) {
                            FileOutputUtil.saveWarningData("${DateUtils.getCurrentTime()}\t${warningType}\t${observeValue}\t${alarmLimitValue}\t${alarmLowerValue}\r\n")
                        }
                    } else {
                        /*无异常情况取消弹窗*/
                        if (alarmDialog.isShowing && alarmDialog.getAlarmType() == alarmType) {
                            alarmDialog.dismiss()
                        }
                        if (warningDialog.isShowing && (warningDialog.getWarningType() == warningType || warningDialog.getWarningType() == AlarmTag.TEMPERATURE_ALARM.value)) {
                            warningDialog.dismiss()
                        }
                    }
                }
            }
        }


    }


    private fun createBlinkAnimation(view: View): ObjectAnimator {
        return ObjectAnimator.ofFloat(
            view,
            View.ALPHA,
            0f, 1f
        ).apply {
            /*默认值*/
            duration = 500
            repeatCount = ValueAnimator.INFINITE
            repeatMode = ValueAnimator.REVERSE
            addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
//                    super.onAnimationEnd(animation)
                    animation.cancel()
                }

            })
        }
    }

    /**
     * 暂停呼吸、心率、体温的闪烁动画
     */
    private fun pauseWarningAndAlarmAnimation() {
        if (rrBlinkAnimation.isRunning) rrBlinkAnimation.cancel()
        if (hrBlinkAnimation.isRunning) hrBlinkAnimation.cancel()
        if (tfBlinkAnimation.isRunning) tfBlinkAnimation.cancel()
        mBinding.ivRrAlarmWarning.visibility = View.INVISIBLE
        mBinding.ivHrAlarmWarning.visibility = View.INVISIBLE
        mBinding.ivTfAlarmWarning.visibility = View.INVISIBLE
    }


    override fun onDestroy() {
        super.onDestroy()
        stopCameraPreview()
        stopEcgChartTimer()
        pauseWarningAndAlarmAnimation()
        if (warningDialog.isShowing) warningDialog.dismiss()
        if (alarmDialog.isShowing) alarmDialog.dismiss()
        AudioPlayer.getInstance(requireContext()).stop()
        USBTransferUtil.getInstance().disconnect()
        bitmapToVideo?.stopRecording()
        stopScreenRecordingService()
        FileOutputUtil.dataQueue_bpm?.clear()
        FileOutputUtil.dataQueue_radar?.clear()
//        if (usbBroadcastReceiver != null) requireActivity().unregisterReceiver(usbBroadcastReceiver)

    }


    /**
     * 停止屏幕录制服务
     */
    private fun stopScreenRecordingService() {
        val service = Intent(requireContext(), ScreenRecordService::class.java)
        if (service != null) {
            requireActivity().stopService(service)
        }
    }


    /**
     * Usb广播监听
     */
    private var lastExecutionTime: Long = 0
    private val interval: Long = TimeUnit.SECONDS.toMillis(3) // 2秒

    private val usbBroadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            when (intent?.action) {
                // USB设备插入
                UsbManager.ACTION_USB_DEVICE_ATTACHED -> {
                    val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                    // 处理设备插入的逻辑
                    val currentTime = System.currentTimeMillis()
                    if (currentTime - lastExecutionTime >= interval) {
                        lastExecutionTime = currentTime
                        mViewModel.setIsPause(false)
                        disconnectDialog.dismiss()
                    }
                }
                // USB设备移除
                UsbManager.ACTION_USB_DEVICE_DETACHED -> {
                    val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                    mViewModel.setIsPause(true)
                    disconnectDialog.show()

                }
            }
        }
    }


}